﻿using Microsoft.Practices.Unity;
using Reactor.Contracts;

namespace Reactor.Container.Unity
{
    internal class UnityServiceRegistrar : IServiceRegistrar
    {
        private readonly IUnityContainer _container;
        private readonly object _lock = new object();

        /// <summary>
        /// Initializes a new instance of the <see cref="UnityServiceRegistrar"/> class.
        /// </summary>
        public UnityServiceRegistrar(IUnityContainer container)
        {
            _container = container;
        }

        #region Implementation of IServiceRegistrar

        /// <summary>
        /// Registers a single instance that is to be returned when the specified type is requested..
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="instance">The instance.</param>
        public void RegisterInstance<T>(object instance) where T : class
        {
            lock (_lock)
            {
                _container.RegisterInstance(typeof (T), instance);
            }
        }

        /// <summary>
        /// Registers the a concrete type to associate with the abstract type.
        /// </summary>
        /// <typeparam name="T">Abstract type</typeparam>
        /// <typeparam name="TConcrete">The concrete type to instantiate when the abstract type is requested.</typeparam>
        public void RegisterType<T, TConcrete>() where TConcrete : T
        {
            lock (_lock)
            {
                _container.RegisterType(typeof (T), typeof (TConcrete));
            }
        }

        #endregion
    }
}
